type Replace<
  X extends string,
  Y extends string,
  Z extends string
> = Y extends ""
  ? X
  : X extends `${infer U}${Y}${infer R}`
  ? `${U}${Z}${R}`
  : X;

// <'foobar', 'bar', 'foo'>, 'foofoo'

type R1 = Replace<"foobar", "bar", "foo">; // foofoo
// type R2 = Replace<"barbbfoo", "bar", "foo">; // foofoo
// type cases = [Expect<Equal<Replace<"foobar", "bar", "foo">, "foofoo">>];
type R3 = Replace<"foobarbar", "", "foo">;
